'use strict'
const Service = require('egg').Service;


const formatToHump = (value) => {
    return value.replace(/\_(\w)/g, (_, letter) => letter.toUpperCase())
};

const params = {}
class WithdrawalService extends Service {

    async isExist(sql, options, conn) {
        let res = await this.app.mysql.query(sql, options, conn)
        return res.length > 0
    }

    async executeSqlSucc(sql, options, conn) {
        conn = conn || this.app.mysql
        let res = await conn.query(sql, options)
        return res.affectedRows
    }

    async executeSqlFirst(sql, options, conn) {
        const res = await this.executeSql(sql, options, conn)
        if (res.length == 0) {
            return null
        }
        return res[0]
    }

    async executeUpdate(name, obj, conn) {
        conn = conn || this.app.mysql
        try {
            let res = await conn.update(name, obj)
            return res
        } catch (e) {
            this.ctx.app.logger.info('executeUpdate error', name, obj, e)
            throw Error(e)
        }
    }

    async executeSql(sql, options, conn) {
        conn = conn || this.app.mysql
        let res = await conn.query(sql, options)
        res = res.map((obj) => {

            const keys = Object.getOwnPropertyNames(obj)
            const ret = {}
            for (const k of keys) {
                ret[formatToHump(k)] = obj[k]
            }

            if(ret.createTime){
                ret.createTime = this.ctx.formatDate(ret.createTime);
            }
            if(ret.updateTime){
                ret.updateTime = this.ctx.formatDate(ret.updateTime);
            }

            return ret
        })
        return res
    }

    async batchUpdate(sql, datas) {
        const conn = await this.app.mysql.beginTransaction()
        try {
            for (const data of datas) {
                await conn.query(sql, data)
            }
            await conn.commit()
        } catch(e) {
            await conn.rollback()
            throw e
        }
        
        return true
    }



    async executeInsert(name, obj, conn) {
        conn = conn || this.app.mysql;
        try {
            let res = await conn.insert(name, obj);
            return res
        } catch (e) {
            this.ctx.app.logger.info('executeInsert error', name, obj, e);
            throw Error(e)
        }
    }



    async queryPageData(sql, options=[]) {
        const conn = await this.app.mysql.getConnection()
        try {
            let datas = await conn.query(sql, options)
            const count = await conn.query('select found_rows() as count')
            datas = datas.map((obj) => {
                const keys = Object.getOwnPropertyNames(obj)
                const ret = {}
                for (const k of keys) {
                    ret[formatToHump(k)] = obj[k]
                }
                return ret
            })

            await conn.release()
            return {list:datas, total: count[0].count}
        } catch(e) {
            this.ctx.app.logger.info('queryPageData error', e.message, sql, options)
            await conn.release()        
            throw new Error(e.message)//服务器错误，请稍后重试
        }
    }

    formatToHump(value){
        return value.replace(/\_(\w)/g, (_, letter) => letter.toUpperCase())
    }

    //fields [{column:'xxx',value:'',options:{where:'and',tname:'',condition:'',format:false}]
    formatSqlWhere(sql, fields) {
        let resultValue = [];
        if (fields && Array.isArray(fields)) {
            for (let i = 0; i < fields.length; i++) {
                let item = fields[i];
                if (Object.prototype.toString.call(item) === '[object Object]') {
                    let options = item.options || {};
                    let where = options.where || 'and';
                    let tname = options.tname ? options.tname + "." : '';
                    let condition = options.condition || '=';
                    let format = options.format;
                    let value = item.value;
                    let column = item.column;
                    if (value !== null && value !== undefined && value !== '') {
                        sql += ` ${where} ${tname}${column} ${condition === 'like' ? condition + ' "%"?"%" ' : condition + ' ? '} `;
                        if (format === true) {
                            value = new Date(value);
                        }
                        resultValue.push(value)
                    }
                }
            }
        }
        return [sql, resultValue];
    }


    addMysqlPageSize(sql, pageIndex, pageSize) {
        pageIndex = pageIndex || 1
        pageIndex = parseInt(pageIndex) - 1;
        if (pageIndex < 0) {
            pageIndex = 0;
        }
        pageSize = pageSize || 10
        pageSize = parseInt(pageSize)
        if (pageSize > 10000) {
            pageSize = 10000
        }
        sql += ` limit ${pageIndex * pageSize}, ${pageSize}`
        return sql
    }

}

module.exports = WithdrawalService;